import pandas as pd
import datetime as dt
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.ticker import MultipleLocator, LinearLocator
from PIL import Image
from mpl_toolkits.mplot3d import Axes3D
import warnings
warnings.filterwarnings(action='ignore')
del data['Unnamed: 0']
data.columns =['age', 'sex', 'job', 'housing', 'saving_accounts', 'checking_account',
'credit_amount', 'duration', 'purpose', 'risk']
data['credit_amount'] = data['credit_amount'].astype(float)
data['risk'] = data['risk'].replace(['good'], 0)
data['risk'] = data['risk'].replace(['bad'], 1)
data['risk'] = data['risk'].astype(int)
data['saving_accounts'] = data['saving_accounts'].fillna('unknown')
data['checking_account'] = data['checking_account'].fillna('unknown')
data.head(3)
orders['date'] = orders['date'].map(lambda x: dt.datetime.strptime(x, '%Y-%m-%d'))
orders = orders.drop(columns=['transactionId'])
orders.head(3)
sns.set_style("whitegrid")
#sns.set_palette('dark')
'darkgrid' — тёмная сетка;
'whitegrid' — белая сетка;
'dark' — тёмный;
'white' — белый;
'ticks' — штриховка.
# текущая палитра
sns.color_palette()
# создать палитру смешением цветов
sns.blend_palette(['blue', 'red'], 10)
# палитра, в которой все серые, кроме одного -- можно подсветить значение
# my_palette = {x: 'gray' for x in tips.day.unique()}
# palette_dict['Sat'] = 'crimson'
#поменять палитру на ...
#sns.color_palette('coolwarm', 20)
Примеры графиков в палитрах:
https://medium.com/@morganjonesartist/color-guide-to-seaborn-palettes-da849406d44f
# показать палитру
sns.palplot(sns.color_palette('coolwarm', 20))
# от matplot: показать доступные стили и применить стиль
#plt.style.available
#plt.style.use('ggplot')
Гистограма с приколами. Может учитывать разделение по многим признакам + зачем-то может становиться kde, ecdf.
plt.figure(figsize=(20, 6))
sns.displot(x='credit_amount', data=data, bins=100, height=6, aspect=1.5);
plt.figure(figsize=(20, 6))
sns.displot(x='credit_amount', data=data, bins=100, height=6, aspect=1.5, hue='sex');
plt.figure(figsize=(20, 6))
sns.displot(x='credit_amount', data=data, bins=100, height=6, aspect=1.5, hue='sex', col='housing');
Оценка плотности ядра (kernel density estimation, или kde). kde рисуется в виде линии и часто повторяет форму гистограмм, но дает больше информации о характере распределения. По факту -- сглаженная гистограмма.
plt.figure(figsize=(20, 6))
sns.kdeplot(data['credit_amount'], shade=True, bw=0.1)
plt.show()
plt.figure(figsize=(20, 6))
sns.kdeplot(data['credit_amount'],
data['age'],
n_levels=20)
# plt.xlim(0, 200)
# plt.ylim(0, 5)
plt.show()
plt.figure(figsize=(20, 6))
data_male = data.query('sex == "male"')
data_female = data.query('sex == "female"')
sns.kdeplot(data_male['credit_amount'],
data_male['age'],
n_levels=10)
sns.kdeplot(data_female['credit_amount'],
data_female['age'],
n_levels=10)
plt.legend(['male', 'female'])
plt.show()
Классическая гистограмма.
plt.figure(figsize=(20, 6))
sns.histplot(x='credit_amount', data=data,
bins=20,
kde=True,
stat='count')
plt.show()
plt.figure(figsize=(20, 6))
sns.histplot(x='credit_amount', data=data,
bins=50,
kde=False,
stat='count',
hue='sex')
plt.show()
plt.figure(figsize=(20, 6))
sns.histplot(x='credit_amount', data=data,
bins=50,
kde=False,
stat='count',
hue='sex',
element='step')
plt.show()
plt.figure(figsize=(20, 6))
sns.histplot(x='credit_amount', data=data,
bins=50,
kde=False,
stat='count',
hue='sex',
multiple='dodge',
shrink=0.8,
fill=False)
plt.show()
plt.figure(figsize=(20, 6))
sns.histplot(x='credit_amount', y='age', data=data,
bins=50,
kde=False,
stat='count',
cbar=True)
plt.show()
plt.figure(figsize=(20, 6))
sns.histplot(x='credit_amount', y='age', data=data,
bins=50,
kde=False,
stat='count',
cbar=True,
hue='sex')
plt.show()
ECDF представляет долю или количество наблюдений, попадающих ниже каждого уникального значения в наборе данных. Виден вклад кажого значения в общую накопленную сумму.
plt.figure(figsize=(10, 6))
sns.ecdfplot(x='duration', data=data)
plt.axvline(data['duration'].mean(), c='red')
plt.show()
plt.figure(figsize=(10, 6))
sns.ecdfplot(x='duration', data=data, hue='purpose')
plt.show()
plt.figure(figsize=(10, 6))
sns.ecdfplot(x='duration', data=data, hue='sex', stat='count')
plt.show()
plt.figure(figsize=(10, 6))
sns.ecdfplot(x='credit_amount', data=data, weights='credit_amount')
plt.axhline(0.5, c='red')
plt.show()
Обычный ящик, но: можно делить на категории (через hue и 2 оси) и много вариантов кастомизации.
plt.figure(figsize=(10, 4))
sns.boxplot(x='age', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.boxplot(x='purpose', y='credit_amount', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.boxplot(x='purpose', y='credit_amount', data=data, hue='sex')
plt.show()
plt.figure(figsize=(20, 6))
sns.boxplot(y='job', x='credit_amount', data=data, orient='h', order=[3, 2, 1, 0], width=0.5, fliersize=3)
plt.show()
Продвинутый вариант boxplot.
plt.figure(figsize=(20, 6))
sns.boxenplot(x='purpose', y='credit_amount', data=data)
plt.show()
Гибрид ящика с усами и KDE.
https://seaborn.pydata.org/generated/seaborn.violinplot.html
plt.figure(figsize=(10, 4))
sns.violinplot(x='age', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.violinplot(x='purpose', y='credit_amount', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.violinplot(x='purpose', y='credit_amount', data=data, hue='sex')
plt.show()
plt.figure(figsize=(20, 6))
sns.violinplot(x='housing', y='credit_amount', data=data, hue='sex', split=True)
plt.show()
plt.figure(figsize=(20, 6))
sns.violinplot(x='housing', y='credit_amount', data=data, hue='sex', split=True, inner='quartile', bw=0.2)
plt.show()
То же назначение, что и у бокс-плота и скрипки. Может быть плохо на больших объёмах данных: много точек.
plt.figure(figsize=(10, 4))
sns.swarmplot(x='age', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.swarmplot(x='purpose', y='credit_amount', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.swarmplot(x='purpose', y='credit_amount', data=data, hue='sex')
plt.show()
plt.figure(figsize=(20, 6))
sns.swarmplot(x='purpose', y='credit_amount', data=data, hue='sex', dodge=True)
plt.show()
Похоже на swarm, но точки расположены случайным образом -- можно вместить больше данных.
plt.figure(figsize=(10, 4))
sns.stripplot(x='age', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.stripplot(x='purpose', y='credit_amount', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.stripplot(x='purpose', y='credit_amount', data=data, hue='sex')
plt.show()
plt.figure(figsize=(20, 6))
sns.stripplot(x='purpose', y='credit_amount', data=data, jitter=0.5)
plt.show()
plt.figure(figsize=(20, 6))
sns.stripplot(x='purpose', y='credit_amount', data=data, jitter=0.2, alpha=0.75)
plt.show()
Бары с особенностями: можно сразу указать, что показывать (сумму, максимум, СКО или что-то ещё).
plt.figure(figsize=(20, 6))
sns.barplot(x='purpose', y='credit_amount', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.barplot(x='purpose', y='credit_amount', data=data, ci=None, estimator=np.std)
plt.show()
plt.figure(figsize=(20, 6))
sns.barplot(x='purpose', y='credit_amount', data=data, ci=None, estimator=np.std, hue='sex')
plt.show()
Бары на минималках: минимум параметров, считает только количество.
plt.figure(figsize=(20, 6))
sns.countplot(x='purpose', data=data)
plt.show()
data['purpose'].value_counts().index
plt.figure(figsize=(20, 6))
sns.countplot(x='purpose', data=data,order=data['purpose'].value_counts().index[::-1])
plt.show()
plt.figure(figsize=(20, 6))
sns.countplot(x='purpose', data=data, hue='job', hue_order=[2, 3, 1, 0], hatch='+', ec='black')
plt.show()
Связи всех со всеми, hist для самой величины + scatter для её связей с иными величинами. Только для numeric, bool. Категории можно вынести в hue.
plt.figure(figsize=(20, 6))
sns.pairplot(data=data, plot_kws={'color':'black'})
plt.show()
plt.figure(figsize=(20, 6))
sns.pairplot(data=data, plot_kws={'color':'black'}, diag_kind='kde')
plt.show()
plt.figure(figsize=(20, 6))
sns.pairplot(data=data, diag_kind='kde', hue='sex')
plt.show()
plt.figure(figsize=(20, 6))
sns.pairplot(data=data, diag_kind='kde', hue='sex', height=1, aspect=1, diag_kws={'color': 'gray', 'alpha': 0.6})
plt.show()
Для 2-ух величин: распределение каждой величины + связь значений. Гибрид hist, scatter.
plt.figure(figsize=(20, 6))
sns.jointplot(x='age', y='duration', data=data, kind='reg')
plt.show()
plt.figure(figsize=(20, 6))
first = sns.jointplot(x='age', y='duration', data=data)
first.plot_joint(sns.kdeplot, color='red', levels=10);
plt.show()
plt.figure(figsize=(20, 6))
sns.jointplot(x='age', y='duration', data=data, hue='sex')
plt.show()
Распределение с помощью тиков. Полезен как дополнение к hist и пр.
plt.figure(figsize=(10, 4))
sns.rugplot(x='duration', data=data, height=0.5, hue='job', palette='plasma')
plt.show()
Взаимное распределение величин. Можно определить общий тренд.
https://seaborn.pydata.org/generated/seaborn.scatterplot.html
plt.figure(figsize=(20, 6))
sns.scatterplot(x='age', y='credit_amount', data=data)
plt.show()
plt.figure(figsize=(20, 6))
sns.scatterplot(x='age', y='credit_amount', data=data, hue='sex')
plt.show()
plt.figure(figsize=(20, 6))
sns.scatterplot(x='age', y='credit_amount', data=data, style='sex')
plt.show()
plt.figure(figsize=(20, 6))
sns.scatterplot(x='age', y='credit_amount', data=data, size='sex', sizes=[10, 100])
plt.show()
plt.figure(figsize=(20, 6))
sns.scatterplot(x='age', y='credit_amount', data=data, hue='job', style='sex', s=100)
plt.show()
Регрессия: линейная и полиномиальная, можно bootstrap, устойчивость к выбросам и пр.
plt.figure(figsize=(20, 6))
sns.regplot(x='duration', y='credit_amount', data=data)
plt.show()
plt.figure(figsize=(20, 6))
plt.xlim(0, 75)
plt.ylim(0, 12000)
sns.regplot(x='duration', y='credit_amount', data=data, scatter=False, ci=None)
plt.show()
plt.figure(figsize=(20, 6))
sns.regplot(x='duration', y='credit_amount', data=data, x_jitter=1)
plt.show()
plt.figure(figsize=(20, 6))
sns.regplot(x='duration', y='credit_amount', data=data, x_estimator=np.mean)
plt.show()
plt.figure(figsize=(20, 6))
sns.regplot(x='duration', y='credit_amount', data=data, order=2)
plt.show()
plt.figure(figsize=(20, 6))
sns.regplot(x='duration', y='credit_amount', data=data, ci=None, scatter_kws={'s': 50, 'alpha': 0.75, 'color': 'lightgray'})
plt.show()
Раскрасить числа.
pivot_1 = data.pivot_table(index=['purpose'],
columns=['housing'],
values=['duration'],
aggfunc={'duration': 'mean'},
fill_value=0)
pivot_1.columns = ['_'.join(col).strip() for col in pivot_1.columns.values]
pivot_1
plt.figure(figsize=(10, 6))
sns.heatmap(data=pivot_1)
plt.show()
plt.figure(figsize=(10, 6))
sns.heatmap(data=data.corr())
plt.show()
plt.figure(figsize=(10, 6))
sns.heatmap(data=pivot_1, cmap='RdBu', annot=True, fmt=".2f",
annot_kws={'fontsize': 16,
'fontweight': 'bold'})
plt.show()
plt.figure(figsize=(10, 6))
sns.heatmap(data=pivot_1, linewidth=1, linecolor='black')
plt.show()
Heatmap с кластеризацией. Самое важное: как разбить на кластеры. Использует scipy для этого.
https://seaborn.pydata.org/generated/seaborn.clustermap.html
plt.figure(figsize=(4, 4))
sns.clustermap(data=pivot_1, figsize=(10, 6))
plt.show()
data_1 = data[['age', 'duration', 'credit_amount']].copy()
plt.figure(figsize=(4, 4))
sns.clustermap(data=data_1, figsize=(10, 6), standard_scale=1)
plt.show()
data['job'].unique()
job_colors=data.job.map({
0: 'blue',
1: 'red',
2: 'green',
3: 'black'})
job_colors.head()
plt.figure(figsize=(4, 4))
sns.clustermap(data=data_1, figsize=(10, 6), standard_scale=1, row_colors=job_colors)
plt.show()
plt.figure(figsize=(4, 4))
sns.clustermap(data=data_1, figsize=(10, 6), standard_scale=1, row_colors=job_colors, cmap='Blues', vmin=0.001)
plt.show()
Не даёт ничего нового, но обеспечивает досутп к разным графикам распределения величин. Параметр kind выбирает базовую функцию уровня осей для использования. Возможность задавать фасеты не отличается от FacetGrid.
plt.figure(figsize=(20, 6))
sns.catplot(x='duration', data=data, kind='box')
plt.show()
plt.figure(figsize=(20, 6))
sns.catplot(x='credit_amount', y='duration', data=data, kind='strip', col='sex', row='housing', height=3, aspect=1)
plt.show()
Ничего нового. Взаимное рспределение 2-ух величин с множеством делений: hue, row, copl, style, size.
plt.figure(figsize=(20, 6))
sns.relplot(x='duration', y='credit_amount', data=data, hue='sex', style='job')
plt.show()
plt.figure(figsize=(20, 6))
sns.relplot(x='duration', y='credit_amount', data=data, hue='sex', kind='line', ci=None, col='job')
plt.show()
Строит линейные регрессии. Фишка, как и у cat, dis, в возможности учитывать параметры.
sns.lmplot(x='age', y='credit_amount', data=data);
sns.lmplot(x='age', y='credit_amount', data=data, hue='job',
ci=None, col='sex', scatter_kws={'alpha': 0.5, 's': 100, 'edgecolor': 'black'});
График, показывает bootstrap.
plt.figure(figsize=(20, 6))
sns.lineplot(x='date', y='revenue', data=orders, n_boot=10, ci=50)
plt.show()
plt.figure(figsize=(20, 6))
sns.lineplot(x='date', y='revenue', data=orders, n_boot=10, ci=None, hue='group')
plt.show()
plt.figure(figsize=(20, 6))
sns.lineplot(x='date', y='revenue', data=orders, n_boot=10, ci=None, style='group')
plt.show()
Создали сетку (facets) -- наполнили её графиками.
grids = sns.FacetGrid(data, col='job')
#grids.map_dataframe(sns.histplot, y='flipper_length_mm');
grids = sns.FacetGrid(data, col='job', sharey=False, hue='sex', palette='plasma')
grids.map_dataframe(sns.scatterplot, x='age', y='credit_amount')
grids.set_axis_labels('Age', 'Credit amount')
grids.set_titles(col_template='Credits by job={col_name}')
plt.show()
Pairplot на максималках. Может не только hist+scatter, но иные сочетания. Обзор всего и вся.
grids = sns.PairGrid(data, height=2)
grids = sns.PairGrid(data)
grids.map(sns.scatterplot);
grids = sns.PairGrid(data, hue='sex', diag_sharey=False)
grids.map_lower(sns.scatterplot)
grids.map_diag(sns.histplot)
grids.map_upper(sns.kdeplot)
grids.add_legend();
Jointplot на максималках. Может не только hist+scatter, но иные сочетания.
grid = sns.JointGrid(data=data, x='duration', y='credit_amount');
grid = sns.JointGrid(data=data, x='duration', y='credit_amount');
grid.plot_joint(sns.regplot)
grid.plot_marginals(sns.kdeplot, fill=True);
grid = sns.JointGrid()
sns.regplot(x=data['duration'], y=data['credit_amount'], ax=grid.ax_joint)
sns.kdeplot(x=data['duration'], ax=grid.ax_marg_x, hue=data['sex'])
sns.histplot(y=data['credit_amount'], ax=grid.ax_marg_y, hue=data['sex']);